#ifndef __CXIMAGE_INTERFACE_H__
#define __CXIMAGE_INTERFACE_H__

#include "interface_base.h"

enum ecximage_format
{
	e_cximage_format_unknown = 0,
	e_cximage_format_bmp = 1,
	e_cximage_format_gif = 2,
	e_cximage_format_jpg = 3,
	e_cximage_format_png = 4,
	e_cximage_format_ico = 5,
	e_cximage_format_tif = 6,
	e_cximage_format_tga = 7,
	e_cximage_format_pcx = 8,
	e_cximage_format_wbmp = 9,
	e_cximage_format_wmf = 10,
	e_cximage_format_jp2 = 11,
	e_cximage_format_jpc = 12,
	e_cximage_format_pgx = 13,
	e_cximage_format_pnm = 14,
	e_cximage_format_ras = 15,
	e_cximage_format_jbg = 16, // no support
	e_cximage_format_mng = 17,
	e_cximage_format_ska = 18,
	e_cximage_format_raw = 19
};

namespace aot{ namespace tt{

class icximage : public virtual aot::tt::interface_base
{
protected:
	virtual ~icximage (){}
public:
	virtual bool query_interface (void** out, const char* key) {return false;}
	virtual const char* interface_name () {return "icximage";}
	virtual void* get_this_impl() = 0;
public:
	/** \addtogroup Initialization */ //@{
	virtual void*	Create(DWORD dwWidth, DWORD dwHeight, DWORD wBpp, DWORD imagetype = 0) = 0;
	virtual bool	Destroy() = 0;
	virtual bool	DestroyFrames() = 0;
	virtual void	Clear(BYTE bval=0) = 0;
	virtual void	Copy( aot::tt::icximage *src, bool copypixels = true, 
		bool copyselection = true, bool copyalpha = true) = 0;

	virtual bool	CreateFromArray(BYTE* pArray,DWORD dwWidth,DWORD dwHeight,
		DWORD dwBitsperpixel, DWORD dwBytesperline, bool bFlipImage) = 0;

	virtual bool	CreateFromMatrix(BYTE** ppMatrix,DWORD dwWidth,DWORD dwHeight,
		DWORD dwBitsperpixel, DWORD dwBytesperline, bool bFlipImage) = 0;

	virtual void	FreeMemory(void* memblock) = 0;
	//@}

	/** \addtogroup Attributes */ //@{
	virtual long	GetSize() = 0;
	virtual BYTE*	GetBits(DWORD row = 0) = 0;
	virtual BYTE	GetColorType() = 0;
	virtual void*	GetDIB()  = 0;
	virtual DWORD	GetHeight()  = 0;
	virtual DWORD	GetWidth()  = 0;
	virtual DWORD	GetEffWidth()  = 0;
	virtual DWORD	GetNumColors()  = 0;
	virtual WORD	GetBpp()  = 0;
	virtual DWORD	GetType()  = 0;
	virtual const char*	GetLastError() = 0;
	virtual DWORD	GetFrameDelay()  = 0;
	virtual void	SetFrameDelay(DWORD d) = 0;
	virtual void	GetOffset(long *x,long *y) = 0;
	virtual void	SetOffset(long x,long y) = 0;
	virtual BYTE	GetJpegQuality()  = 0;
	virtual void	SetJpegQuality(BYTE q) = 0;
	virtual float	GetJpegQualityF()  = 0;
	virtual void	SetJpegQualityF(float q) = 0;
	virtual BYTE	GetJpegScale()  = 0;
	virtual void	SetJpegScale(BYTE q) = 0;
	virtual long	GetXDPI()  = 0;
	virtual long	GetYDPI()  = 0;
	virtual void	SetXDPI(long dpi) = 0;
	virtual void	SetYDPI(long dpi) = 0;
	virtual DWORD	GetClrImportant()  = 0;
	virtual void	SetClrImportant(DWORD ncolors = 0) = 0;
	virtual long	GetProgress()  = 0;
	virtual long	GetEscape()  = 0;
	virtual void	SetProgress(long p) = 0;
	virtual void	SetEscape(long i) = 0;
	virtual long	GetTransIndex()  = 0;
	virtual RGBQUAD	GetTransColor() = 0;
	virtual void	SetTransIndex(long idx) = 0;
	virtual void	SetTransColor(RGBQUAD rgb) = 0;
	virtual bool	IsTransparent()  = 0;
	virtual DWORD	GetCodecOption(DWORD imagetype = 0) = 0;
	virtual bool	SetCodecOption(DWORD opt, DWORD imagetype = 0) = 0;
	virtual DWORD	GetFlags()  = 0;
	virtual void	SetFlags(DWORD flags, bool bLockReservedFlags = true) = 0;
	virtual BYTE	GetDisposalMethod()  = 0;
	virtual void	SetDisposalMethod(BYTE dm) = 0;
	virtual bool	SetType(DWORD type) = 0;
	virtual bool	GetRetreiveAllFrames()  = 0;
	virtual void	SetRetreiveAllFrames(bool flag) = 0;
	virtual bool    GetFrame(aot::tt::icximage **out, long nFrame)  = 0;

	//@}

	/** \addtogroup Palette
	* These functions have no effects on RGB images and in this case the returned value is always 0.
	* @{ */
	virtual bool	IsGrayScale() = 0;
	virtual bool	IsIndexed()  = 0;
	virtual DWORD	GetPaletteSize() = 0;
	virtual RGBQUAD* GetPalette()  = 0;
	virtual RGBQUAD GetPaletteColor(BYTE idx) = 0;
	virtual bool	GetPaletteColor(BYTE i, BYTE* r, BYTE* g, BYTE* b) = 0;
	virtual BYTE	GetNearestIndex(RGBQUAD c) = 0;
	virtual void	BlendPalette(COLORREF cr,long perc) = 0;
	virtual void	SetGrayPalette() = 0;
	virtual void	SetPalette(DWORD n, BYTE *r, BYTE *g, BYTE *b) = 0;
	virtual void	SetPalette(RGBQUAD* pPal,DWORD nColors=256) = 0;
	virtual void	SetPaletteColor(BYTE idx, BYTE r, BYTE g, BYTE b, BYTE alpha=0) = 0;
	virtual void	SetPaletteColor(BYTE idx, RGBQUAD c) = 0;
	virtual void	SetPaletteColor(BYTE idx, COLORREF cr) = 0;
	virtual void	SwapIndex(BYTE idx1, BYTE idx2) = 0;
	virtual void	SwapRGB2BGR() = 0;
	virtual void	SetStdPalette() = 0;
	//@}

	/** \addtogroup Pixel */ //@{
	virtual bool	IsInside(long x, long y) = 0;
	virtual bool	IsTransparent(long x,long y) = 0;
	virtual RGBQUAD GetPixelColor(long x,long y, bool bGetAlpha = true) = 0;
	virtual BYTE	GetPixelIndex(long x,long y) = 0;
	virtual BYTE	GetPixelGray(long x, long y) = 0;
	virtual void	SetPixelColor(long x,long y,RGBQUAD c, bool bSetAlpha = false) = 0;
	virtual void	SetPixelColor(long x,long y,COLORREF cr) = 0;
	virtual void	SetPixelIndex(long x,long y,BYTE i) = 0;
	virtual void	DrawLine(int StartX, int EndX, int StartY, int EndY, RGBQUAD color, bool bSetAlpha=false) = 0;
	virtual void	DrawLine(int StartX, int EndX, int StartY, int EndY, COLORREF cr) = 0;
	virtual void	BlendPixelColor(long x,long y,RGBQUAD c, float blend, bool bSetAlpha = false) = 0;
	//@}

	/** \addtogroup Painting */ //@{
	virtual long	Blt(HDC pDC, long x=0, long y=0) = 0;
	virtual HBITMAP MakeBitmap(HDC hdc = NULL) = 0;
	virtual HANDLE	CopyToHandle() = 0;
	virtual bool	CreateFromHANDLE(HANDLE hMem) = 0;		//Windows objects (clipboard)
	virtual bool	CreateFromHBITMAP(HBITMAP hbmp, HPALETTE hpal=0) = 0;	//Windows resource
	virtual bool	CreateFromHICON(HICON hico) = 0;
	virtual long	Draw(HDC hdc, const RECT& rect, RECT* pClipRect=NULL, bool bSmooth = false) = 0;	
	virtual long	Stretch(HDC hdc, const RECT& rect, DWORD dwRop = SRCCOPY) = 0;
	virtual long	Tile(HDC hdc, RECT *rc) = 0;
	virtual long	Draw2(HDC hdc, const RECT& rect) = 0;
	virtual long	DrawString(HDC hdc, long x, long y, const char* text, RGBQUAD color, const TCHAR* font, long lSize=0, long lWeight=400, BYTE bItalic=0, BYTE bUnderline=0, bool bSetAlpha=false) = 0;
	//@}

	// file operations
	/** \addtogroup Decode */ //@{

	virtual bool LoadResource(HRSRC hRes, DWORD imagetype, HMODULE hModule=NULL) = 0;

	// For UNICODE support: char -> TCHAR
	virtual bool Load(const char* filename, DWORD imagetype=0) = 0;
	//bool Load(const char * filename, DWORD imagetype=0) = 0;
	virtual bool Decode(FILE * hFile, DWORD imagetype) = 0;
	virtual bool Decode(BYTE * buffer, DWORD size, DWORD imagetype) = 0;
	virtual bool CheckFormat(BYTE * buffer, DWORD size, DWORD imagetype = 0) = 0;
	//@}

	/** \addtogroup Attributes */ //@{
	//misc.
	virtual bool IsValid() =0;
	virtual bool IsEnabled() =0;
	virtual void Enable(bool enable=true) = 0;

	// frame operations
	virtual long GetNumFrames() = 0;
	virtual long GetFrame() = 0;
	virtual void SetFrame(long nFrame) = 0;
	//@}

	/** \addtogroup Transformations */ //@{
	// image operations
	virtual bool Rotate(float angle) = 0;
	virtual bool DecreaseBpp(DWORD nbit, bool errordiffusion, RGBQUAD* ppal = 0, DWORD clrimportant = 0) = 0;
	virtual bool IncreaseBpp(DWORD nbit) = 0;
	virtual bool Crop(const RECT& rect) = 0;
	virtual bool CropTo(const RECT& rect, aot::tt::icximage** out ) = 0;
	//@}

	virtual bool ShiftRGB(long r, long g, long b) = 0;
	virtual bool Colorize(BYTE hue, BYTE sat, float blend = 1.0f) = 0;
};

}}

#endif /* __CXIMAGE_INTERFACE_H__ */